import tnx from '@/tnx.js';
import DependencyClass from './DependencyClass.js';
import DependencyLibType from '../enums/DependencyLibType.js';
import ModelingClass from './ModelingClass.js';

/**
 * 依赖库
 */
export default class DependencyLib {

    /**
     *
     * @type {DependencyLibType}
     */
    type = null;
    groupId = '';
    artifactId = '';
    version = '';
    modelingPath = '';
    /**
     * 建模文件的最近同步时间
     * @type {Date}
     */
    modelingSyncTime = null;
    favoriteClassNames = [];
    /**
     * @type {[DependencyClass]}
     */
    classes = [];
    /**
     * 初始化状态，null-未开始初始化，false-正在进行初始化，true-已完成初始化
     * @type {Boolean}
     */
    initialized = null;

    /**
     *
     * @param {DependencyLibType} type
     */
    constructor(type) {
        this.type = type;
    }

    static of(object) {
        if (typeof object !== 'object') {
            return undefined;
        }
        let type = DependencyLibType.validate(object.type);
        let lib = new DependencyLib(type);
        lib.update(object);
        return lib;
    }

    update(object) {
        tnx.util.object.rewriteSimpleDefined(this, object);
        if (typeof object === 'object') {
            if (object.favoriteClassNames) {
                this.favoriteClassNames = [...object.favoriteClassNames];
            }
            if (object.classes) {
                this.classes = object.classes.map(c => DependencyClass.of(c));
            }
        }
        return this;
    }

    clone() {
        return DependencyLib.of(this);
    }

    getName() {
        return this.groupId + ':' + this.artifactId + ':' + this.version;
    }

    matches(other) {
        if (typeof other === 'object') {
            return this.groupId === other.groupId && this.artifactId === other.artifactId
                && this.version === other.version;
        }
        return false;
    }

    getFavoriteOrdinal(className) {
        return this.favoriteClassNames.indexOf(className) + 1; // 偏爱序号从1开始计数
    }

    findClass(clazz) {
        return this.classes.find(c => c.matches(clazz));
    }

    pushClass(origin) {
        let clazz = this.findClass(origin);
        if (!clazz) {
            clazz = new DependencyClass(origin);
            if (origin instanceof ModelingClass) {
                clazz.lastSaveTime = origin.saveTime;
            }
            clazz.favoriteOrdinal = this.getFavoriteOrdinal(clazz.getName());
            this.classes.push(clazz);
        }
        return clazz;
    }

    sortClasses() {
        this.classes.sort((dc1, dc2) => {
            let typeOrder1 = dc1.isPrimitive() ? 0 : 1;
            let typeOrder2 = dc2.isPrimitive() ? 0 : 1;
            if (typeOrder1 !== typeOrder2) {
                return typeOrder1 - typeOrder2;
            } else {
                return dc1.getName().localeCompare(dc2.getName());
            }
        });
    }

    queryClass(keyword) {
        let classes = [];
        keyword = keyword ? keyword.trim() : '';
        if (keyword) {
            for (let clazz of this.classes) {
                if (clazz.getName().toLowerCase().includes(keyword.toLowerCase())) {
                    classes.push(clazz);
                }
            }
        }
        return classes;
    }

    needsSync() {
        for (let clazz of this.classes) {
            if (clazz.needsSync()) {
                return true;
            }
        }
        return false;
    }

    getModelingSaveTime() {
        let modelingSaveTime = null;
        // 取所有引用类的最晚的最近保存时间作为库的模型保存时间，这意味着只要有一个模型类的保存时间晚于同步时间，就需要同步
        for (let clazz of this.classes) {
            // 被引用的才参与比较
            if (clazz.referencedNum && clazz.lastSaveTime) {
                if (!modelingSaveTime || clazz.lastSaveTime > modelingSaveTime) {
                    modelingSaveTime = clazz.lastSaveTime;
                }
            }
        }
        return modelingSaveTime;
    }

}
